/*
 * $Id: MplDate.java,v 1.2 2008/07/10 06:52:05 quy Exp $
 * Copyright(c) 2007-2010 makepolo.com, All Rights Reserved.
 */
package com.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * ���ڴ�����
 * @author xied
 * @version 1.0 2007-11-13
 * @since 1.0
 */
public final class MyDate {
	/** Ĭ�����ڸ�ʽ */
	public static final String DEF_DATE_FORMAT = "yyyy-MM-dd";
	/** Ĭ��ʱ���ʽ */
	public static final String DEF_TIME_FORMAT = "HH:mm:ss";
	/** Ĭ������ʱ���ʽ */
	public static final String DEF_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	/** ��ȷ������ʱ���ʽ */
	public static final String MINUTE_FORMAT = "yyyy-MM-dd HH:mm";

	/** Ĭ������ƥ���ʽ */
	public static final String DEF_DATE_PATTERN = "\\d{4}\\-\\d{2}-\\d{2}";
	/** Ĭ������ʱ��ƥ���ʽ */
	public static final String DEF_DATETIME_PATTERN = "\\d{4}\\-\\d{2}-\\d{2}\\p{javaWhitespace}\\d{2}:\\d{2}:\\d{2}";
	
	/**
	 * ���캯��(��)
	 */
	private MyDate() {}
	
	/**
	 * ȡ��ϵͳ��ǰʱ���
	 * @return ϵͳ��ǰʱ�������
	 */
	public static Timestamp getSysTimestamp() {
		return new Timestamp(System.currentTimeMillis());
	}
	
	/**
	 * ��yyyy-MM-dd��ʽ���ַ�ת��Ϊ���ڶ���
	 * @param date yyyy-MM-dd��ʽ�ַ�
	 * @return ת��������ڶ����޷�ת��ʱ����null
	 */
	public static Date getDate(String date) {
		if (!matchesPattern(date, DEF_DATE_PATTERN)) return null;
		return parseDate(date, DEF_DATE_FORMAT);
	}
	
	/**
	 * ��yyyy-MM-dd��ʽ���ַ�ת��Ϊʱ�������
	 * @param date yyyy-MM-dd��ʽ�ַ�
	 * @return ת�����ʱ��������޷�ת��ʱ����null
	 */
	public static Timestamp getTimestamp(String date) {
		if (!matchesPattern(date, DEF_DATE_PATTERN)) return null;
		return new Timestamp(parseDate(date, DEF_DATE_FORMAT).getTime());
	}
	
	/**
	 * ��yyyy-MM-dd HH:mm:ss��ʽ���ַ�ת��Ϊ���ڶ���
	 * @param datetime yyyy-MM-dd HH:mm:ss��ʽ�ַ�
	 * @return ת��������ڶ����޷�ת��ʱ����null
	 */
	public static Date getDateTime(String datetime) {
		if (!matchesPattern(datetime, DEF_DATETIME_PATTERN)) return null;
		return parseDate(datetime, DEF_DATETIME_FORMAT);
	}
	
	/**
	 * ��yyyy-MM-dd HH:mm:ss��ʽ���ַ�ת��Ϊʱ����ڶ���
	 * @param datetime yyyy-MM-dd HH:mm:ss��ʽ�ַ�
	 * @return ת�����ʱ��������޷�ת��ʱ����null
	 */
	public static Timestamp getDateTimeStamp(String datetime) {
		if (!matchesPattern(datetime, DEF_DATETIME_PATTERN)) return null;
		return new Timestamp(parseDate(datetime, DEF_DATETIME_FORMAT).getTime());		
	}
	
	/**
	 * ��ָ����ʽ���ַ����ת��Ϊ���ڶ���
	 * @param date �ַ�
	 * @param pattern ָ���ĸ�ʽ
	 * @return ת��������ڣ��޷�ת��ʱ����null
	 */
	public static Date getDate(String date, String pattern) {
		return getDate(date, pattern, null);
	}
	
	/**
	 * ��ָ����ʽ���ַ����ת��Ϊ���ڶ���
	 * @param date �ַ�
	 * @param pattern ָ���ĸ�ʽ
	 * @param defVal Ĭ�Ϸ���ֵ
	 * @return ת��������ڣ��޷�ת��ʱ����defValָ��ֵ
	 */
	public static Date getDate(String date, String pattern, Date defVal) {
		if (date == null || pattern == null) return null;
		Date ret = parseDate(date, pattern);
		return (ret == null) ? defVal : ret;
	}
	
	/**
	 * ���ָ���ĸ�ʽ��ʽ�������ַ�ת��Ϊ���ڶ���
	 * @param date �����ַ�
	 * @param format ָ����ʽ
	 * @return ��ʽ�������ڶ���
	 */
	private static Date parseDate(String date, String format) {
		Date d;
		try {
			d = new SimpleDateFormat(format).parse(date);
		} catch (ParseException e) {
			d = null;
		}
		return d;
	}
	
	/**
	 * ��������ַ��Ƿ���ָ����ʽƥ��
	 * @param input �����ַ�
	 * @param pattern ����ʽ
	 * @return
	 * <li>true��ƥ��</li>
	 * <li>false����ƥ��</li>
	 */
	private static boolean matchesPattern(String input, String pattern) {
		return (input != null) && (input.matches(pattern));
	}
	
	/**
	 * �����ڶ����ʽ����yyyy-mm-dd���͵��ַ�
	 * @param date ���ڶ���
	 * @return ��ʽ������ַ��޷���ʽ��ʱ������null
	 */
	public static String formatDate(Date date) {
		return formatDateToString(date, DEF_DATE_FORMAT);
	}
	
	/**
	 * �����ڶ����ʽ����HH:mm:ss���͵��ַ�
	 * @param date ���ڶ���
	 * @return ��ʽ������ַ��޷���ʽ��ʱ������null
	 */
	public static String formatTime(Date date) {
		return formatDateToString(date, DEF_TIME_FORMAT);
	}
	
	/**
	 * �����ڶ����ʽ����yyyy-MM-dd HH:mm:ss���͵��ַ�
	 * @param date ���ڶ���
	 * @return ��ʽ������ַ��޷���ʽ��ʱ������null
	 */
	public static String formatDateTime(Date date) {
		return formatDateToString(date, DEF_DATETIME_FORMAT);
	}
	
	/**
	 * �����ڶ����ʽ����yyyy-MM-dd HH:mm���͵��ַ�
	 * @param date ���ڶ���
	 * @return ��ʽ������ַ��޷���ʽ��ʱ������null
	 */
	public static String formateMinuteDate(Date date) {
		return formatDateToString(date, MINUTE_FORMAT);
	}
	
	/**
	 * �����ڶ����ʽ����ָ���ĸ�ʽ�ַ�
	 * @param date ���ڶ���
	 * @param format ��ʽ
	 * @return ��ʽ������ַ��޷���ʽ��ʱ������null
	 */
	private static String formatDateToString(Date date, String format) {
		if (date == null) return null;
		return new SimpleDateFormat(format).format(date);
	}
	
	/**
	 * �����ڶ����ʽ����ָ����ʽ���ַ�
	 * @param date ���ڶ���
	 * @param format ��ʽ
	 * @return ��ʽ������ַ��޷���ʽ��ʱ������null
	 */
	public static String formatDate(Date date, String format) {
		if (date == null || format == null) return null;
		String ret;		
		try {
			ret = new SimpleDateFormat(format).format(date);
		} catch (RuntimeException e) {
			ret = null;
		}
		return ret;
	}
	
	/**
	 * ȡ��ָ�����������µ����һ�����ڶ���
	 * @param d ָ������
	 * @return ָ�����ڵ��µ����һ�����ڶ�����ָ������Ϊnullʱ�����ص�ǰ�µ����һ�����ڶ���
	 */
	public static Date getLastDayObjectInMonth(Date d) {
		Calendar cal = Calendar.getInstance();
		if (d != null) cal.setTime(d);
		cal.add(Calendar.MONTH, 1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.add(Calendar.DAY_OF_MONTH, -1);
		return cal.getTime();
	}
	
	/**
	 * ȡ��ָ�����������µ����һ������ֵ
	 * @param d ָ������
	 * @return ���µ����һ������ֵ����ָ������Ϊnullʱ�����ص�ǰ�µ����һ������ֵ
	 * @see #getLastDayObjectInMonth(Date)
	 */
	public static int getLastDayInMonth(Date d) {
		Date date = getLastDayObjectInMonth(d);
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_MONTH);
	}
}
